/**
* @copyright Copyright (c) 2022-2023 Grab GEO IoT Team
* @file observer.h
* @author wenzhu.tu
* @version 0.1
* @date 2023-03-22
* @brief observer mode
*/

#ifndef OBSERVER_H
#define OBSERVER_H

/******************************* Includes ********************************/
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include  <stdlib.h>

#include "log_net.h"

#ifdef __cplusplus
extern "C"
{
#endif

/******************************* Macros ******************************/
#define OBSERVER_TAG ("OBS-M")
#define OBSERVER_E(...)  util_loge(OBSERVER_TAG, __VA_ARGS__)
#define OBSERVER_I(...)  util_logi(OBSERVER_TAG, __VA_ARGS__)
#define OBSERVER_D(...)  util_logd(OBSERVER_TAG, __VA_ARGS__)
#define OBSERVER_HEXDUMP(with, buf, len) util_log_hex_dump(OBSERVER_TAG, with, buf, len)

/******************************* Typedef ******************************/
typedef void (*event_callback)(int id, void *data);

typedef struct observer_handle
{
    event_callback cb;
    pthread_mutex_t mutex;
    struct observer_handle *last;
    struct observer_handle *next;
}observer_handle_t;
/******************************* Variables ******************************/

/******************************* Functions ******************************/

/**
 * @brief init observer
 * @return observer_handle_t* NULL is fail
 */
observer_handle_t *observer_init();

/**
 * @brief deinit observer
 * @param handle observer_handle_t **
 */
void observer_deinit(observer_handle_t **handle);

/**
 * @brief call observer callback
 * @param handle observer_handle_t *
 * @param id 
 * @param data 
 */
void observer_process(observer_handle_t *handle, int id, void *data);

/**
 * @brief add new observer callback
 * @param handle observer_handle_t * 
 * @param cb event_callback
 * @return int -1 error 0 success
 */
int  observer_add(observer_handle_t *handle, event_callback cb);

/**
 * @brief del observer
 * @param handle observer_handle_t * 
 * @param cb event_callback
 * @return int -1 error 0 success
 */
int  observer_del(observer_handle_t *handle, event_callback cb);

void observer_test();

#ifdef __cplusplus
}
#endif

#endif
/******************************* End of file ******************************/